package com.luocc.tim.recycler;


import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.LinearLayout;
import android.widget.Scroller;
import android.widget.TextView;

import androidx.annotation.NonNull;

import com.luocc.tim.R;
import com.luocc.tim.utils.TimUtils;


/**
 * 如果滑动到最上方了，
 */
public class RefreshLayout extends LinearLayout {

    private TextView refresh;
    private ChatListRecycler chatList;
    private final Scroller mScroller;
    private final Handler mHandler;
    private boolean mChildMove = false;

    private int mRefreshAreaHeight = 500;
    public static int mRefreshHeight = 80;

    public static final int MSG_REFRESH_RUNNING = 1;
    public static final int MSG_REFRESH_FINISHED = 2;

    public static final String[] REFRESH_TEXT = {"刷新中.", "刷新中..", "刷新中...", "刷新中....", "刷新成功"};

    private float mLastY;

    public static final String TAG = "RefreshLayout";

    public RefreshLayout(Context context) {
        this(context, null);
    }

    public RefreshLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RefreshLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mRefreshHeight = TimUtils.dip2px(context, mRefreshHeight);
        mRefreshAreaHeight = TimUtils.dip2px(context, mRefreshAreaHeight);
        mScroller = new Scroller(context);
        mHandler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(@NonNull Message msg) {
                switch (msg.what) {
                    case MSG_REFRESH_RUNNING:
                        refresh.setText((CharSequence) msg.obj);
                        break;
                    case MSG_REFRESH_FINISHED:
                        mScroller.startScroll(0, getScrollY(), 0, -getScrollY());
                        invalidate();
                        break;
                }
            }
        };
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        refresh = findViewById(R.id.refresh);
        chatList = findViewById(R.id.chat_list);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.d(TAG, "dispatchTouchEvent: action = " + ev.getAction());
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mChildMove = false;
                break;
            case MotionEvent.ACTION_MOVE:
                if (mChildMove) {
                    dispatchTouchEvent(
                            MotionEvent.obtain(
                                    SystemClock.uptimeMillis(),
                                    SystemClock.uptimeMillis(),
                                    MotionEvent.ACTION_DOWN,
                                    ev.getX(),
                                    ev.getY(),
                                    ev.getMetaState()));
                    return false;
                }
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.d(TAG, "onInterceptTouchEvent: action = " + ev.getAction());
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mLastY = ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                boolean moveDown = ev.getY() - mLastY > 0;
                Log.d(TAG, "onInterceptTouchEvent: moveDown ? " + moveDown);
                if (moveDown && !chatList.canScrollVertically(-1)) {
                    return true;
                }
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.d(TAG, "onTouchEvent: action = " + event.getAction());
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_MOVE:
                float y = event.getY();
                float move = mLastY - y;
                mLastY = y;
                float dumpingFactor;
                if (move < 0) {
                    dumpingFactor = mRefreshAreaHeight / (getScrollY() + (float) mRefreshAreaHeight) + 1.5f;
                } else {
                    dumpingFactor = 1;
                }
                Log.d(TAG, "onTouchEvent: move = " + move);
                if (getScrollY() < 0 || move < 0) {
                    Log.d(TAG, "onTouchEvent: <");
                    scrollBy(0, (int) (move / dumpingFactor));
                    return true;
                } else {
                    mChildMove = true;
                    return false;
                }
            case MotionEvent.ACTION_UP:
                if (getScrollY() > -mRefreshHeight) {
                    Log.d(TAG, "onTouchEvent: 1");
                    mScroller.startScroll(0, getScrollY(), 0, -getScrollY());
                    invalidate();
                    break;
                } else {
                    Log.d(TAG, "onTouchEvent: 2");
                    mScroller.startScroll(0, getScrollY(), 0, -(getScrollY() + mRefreshHeight));
                    invalidate();
                }
                new Thread(() -> {
                    int time = 500;
                    for (int i = 0; i < 5; i++) {
                        Message message = mHandler.obtainMessage(MSG_REFRESH_RUNNING);
                        message.obj = REFRESH_TEXT[i];
                        if (i == 4) {
                            time = 200;
                        }
                        mHandler.sendMessage(message);
                        try {
                            Thread.sleep(time);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    mHandler.sendEmptyMessage(MSG_REFRESH_FINISHED);
                }).start();
                break;
        }
        return super.onTouchEvent(event);
    }

    @Override
    public void computeScroll() {
        super.computeScroll();
        if (mScroller.computeScrollOffset()) {
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            invalidate();
        }
    }
}
